﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace WPFTemplateLib.Controls.XUI
{
	/// <summary>
	/// 加载时带动画效果的 ItemsControl（动画通过项 <see cref="FormItem"/> 实现）<para/>
	/// 来自：https://www.uoften.com/article/199078.html
	/// </summary>
	public class Form : ItemsControl
	{
		static Form()
		{
			DefaultStyleKeyProperty.OverrideMetadata(typeof(Form), new FrameworkPropertyMetadata(typeof(Form)));
		}

		public double HeaderWidth
		{
			get { return (double)GetValue(HeaderWidthProperty); }
			set { SetValue(HeaderWidthProperty, value); }
		}
		public static readonly DependencyProperty HeaderWidthProperty =
			DependencyProperty.Register(nameof(HeaderWidth), typeof(double), typeof(Form), new PropertyMetadata(70D));

		public int Rows
		{
			get { return (int)GetValue(RowsProperty); }
			set { SetValue(RowsProperty, value); }
		}
		public static readonly DependencyProperty RowsProperty =
			DependencyProperty.Register(nameof(Rows), typeof(int), typeof(Form), new PropertyMetadata(0));

		public int Columns
		{
			get { return (int)GetValue(ColumnsProperty); }
			set { SetValue(ColumnsProperty, value); }
		}
		public static readonly DependencyProperty ColumnsProperty =
			DependencyProperty.Register(nameof(Columns), typeof(int), typeof(Form), new PropertyMetadata(1));

	}

	/// <summary>
	/// 加载时带动画的列表项
	/// </summary>
	public class FormItem : ListBoxItem
	{
		/* FormItem 是从 ListBoxItem 继承而来，而 ListBoxItem 又是从 ContentControl 继承而来的，
		 所以可以添加到任何具有 Content 属性的控件中去，常见的 ListBoxItem 可以放到 ListBox 中，也可以放到 ItemsControl 中去 */

		static FormItem()
		{
			DefaultStyleKeyProperty.OverrideMetadata(typeof(FormItem), new FrameworkPropertyMetadata(typeof(FormItem)));
		}

		public FormItem()
		{
			System.Windows.Media.TranslateTransform transform = EnsureRenderTransform<System.Windows.Media.TranslateTransform>(this);
			transform.X = transform.Y = 100;
			Opacity = 0;

			IsVisibleChanged += FormItem_IsVisibleChanged;
		}

		private void FormItem_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
		{
			if (this.Parent is Form)
			{
				if (!IsVisible)
				{
					int index = (this.Parent as Form).Items.IndexOf(this);
					System.Windows.Media.TranslateTransform transform = EnsureRenderTransform<System.Windows.Media.TranslateTransform>(this);
					DoubleAnimation da = new DoubleAnimation()
					{
						From = 0,
						To = 100,
						EasingFunction = new CircleEase { EasingMode = EasingMode.EaseOut }
					};
					transform.BeginAnimation(System.Windows.Media.TranslateTransform.XProperty, da);
					transform.BeginAnimation(System.Windows.Media.TranslateTransform.YProperty, da);
					DoubleAnimation daopacity = new DoubleAnimation
					{
						From = 1,
						To = 0,
					};
					this.BeginAnimation(UIElement.OpacityProperty, daopacity);
				}
				else
				{
					int index = (this.Parent as Form).Items.IndexOf(this);
					System.Windows.Media.TranslateTransform transform = EnsureRenderTransform<System.Windows.Media.TranslateTransform>(this);
					DoubleAnimation da = new DoubleAnimation()
					{
						From = 100,
						To = 0,
						BeginTime = TimeSpan.FromMilliseconds(100 * (index + 1)),
						Duration = TimeSpan.FromMilliseconds(666),
						EasingFunction = new CircleEase { EasingMode = EasingMode.EaseOut }
					};
					transform.BeginAnimation(System.Windows.Media.TranslateTransform.XProperty, da);
					transform.BeginAnimation(System.Windows.Media.TranslateTransform.YProperty, da);
					DoubleAnimation daopacity = new DoubleAnimation
					{
						From = 0,
						To = 1,
						BeginTime = TimeSpan.FromMilliseconds(100 * (index + 1)),
						Duration = TimeSpan.FromMilliseconds(666),
						EasingFunction = new CircleEase { EasingMode = EasingMode.EaseOut }
					};
					this.BeginAnimation(UIElement.OpacityProperty, daopacity);
				}
			}
		}

		/// <summary>
		/// 获取指定 <see cref="UIElement"/> 对象的 RenderTransform，没有时给它创建一个并赋值
		/// </summary>
		/// <typeparam name="T">Transform 子类型</typeparam>
		/// <param name="uiTarget">UI 对象</param>
		/// <returns>对象的 RenderTransform</returns>
		private T EnsureRenderTransform<T>(UIElement uiTarget)
			where T : Transform
		{
			if (uiTarget.RenderTransform is T)
				return uiTarget.RenderTransform as T;
			else
			{
				T instance = typeof(T).Assembly.CreateInstance(typeof(T).FullName) as T;
				uiTarget.RenderTransform = instance;
				return instance;
			}
		}

		public string Title
		{
			get { return (string)GetValue(TitleProperty); }
			set { SetValue(TitleProperty, value); }
		}
		public static readonly DependencyProperty TitleProperty =
			DependencyProperty.Register(nameof(Title), typeof(string), typeof(FormItem), new PropertyMetadata(""));


		public ImageSource Icon
		{
			get { return (ImageSource)GetValue(IconProperty); }
			set { SetValue(IconProperty, value); }
		}
		public static readonly DependencyProperty IconProperty =
			DependencyProperty.Register(nameof(Icon), typeof(ImageSource), typeof(FormItem), new PropertyMetadata(null));

	}
}
